#include "device.h"
#include "../finger.h"
#include "fpc_store.h"
#include "osal.h"

/* 调试打印接口 */
#define FINGER_LOG(format, ...)    		__OSAL_LOG( "[finger.c] " format, ##__VA_ARGS__)

/* 指纹检测事件 */
#define EVENT_FINGER_DETECT             (0X00000001)    //指纹检测事件
#define EVENT_INIT_FINGER               (0X00000002)
#define EVENT_MSG_BUFF_PROCESS          (0X00000004)


/* FINGER组件的NV大小 */
#ifdef FINGER_INDEX_SAVE_EEPROM
    #define FINGER_NV_SIZE                  (50) 	        
#else
    #define FINGER_NV_SIZE                  (10) 	        //目前实际只用到2 Byte
#endif

/* NV FINGER组件初始化标识*/
#define FINGER_NV_INIT_FLAG			    0xFA

#define FINGER_TASK_QUEUE_SIZE          (20)
#define FINGER_TASK_PRIORITY            (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 2)
#define FINGER_TASK_STACK_SIZE          (1024 * 2)
#define MAX_REMAININ                    (12)            //最大采图次数
#define SENSOR_SLEEP_PERIOD_3022        (100)           //指纹传感器的睡眠时间间隔

/* 指纹外部消息 */
#define PS_START                        0x55            //启动命令
#define PS_WORKMODE                     0x53            //切换工作模式

/* 定义虚拟硬件接口 */
#define IRQ_VHW_FINGER                  vPIN_I5

/* 定时时间 */
#define FINGER_PROCESSOR_TIME           50


typedef struct
{
    uint32_t msg_type;
    Finger_WorkMode_enum_t mode;
} Finger_Msg_Data_stu_t;

//指纹运行状态数据
typedef struct
{
    WorkMode_enum_t mode;                           //工作模式
    size_t template_max_size;                       //模板大小
    fpc_bep_sensor_type_t sensor_type;              //sensor的型号
    bool sensor_init_flag;                          //sensor初始化成功标志
    uint16_t sensor_sleep_period;
    fpc_bep_image_t *image;                         //采图指针
    fpc_bep_template_t *template_read;              //读取模板指针
    uint8_t enroll_num;                             //注册次数
    fpc_bep_enrollment_status_t enrollment_status;  //注册操作状态
    VerifList_t verif_list;                         //验证列表
    int32_t nbr_of_images;
} Finger_Status_Data_stu_t;

/* 指纹组件状态类型 */
typedef enum 
{
	FPSTATUS_INIT,			                        //初始状态
    FPSTATUS_DETECT_FINGER,                         //超时时间内检测手指是否存在
	FPSTATUS_GET_IMAGE_OK_HANDLE,					//采图成功处理
    FPSTATUS_WAIT_FINGER_AWAY_START,                //开始等待手指挪开
    FPSTATUS_WAIT_FINGER_AWAY_ING,                  //超时时间内检测手指是否存在结果返回,正在等待手指挪开
    FPSTATUS_DORMANCY,                              //休眠操作
    FPSTATUS_END,                                   //结束状态
}FingerStatus_enum_t;

/* 指纹初始化标志 */
static FlagStatus finger_init_flag = RESET;

/* 指纹启动标志 */
static FlagStatus start_flag = RESET;  

/* 注册指纹开始标志 */
static FlagStatus finsh_flag = RESET;

/* 指纹存储编号 */
static uint8_t temp_save_num = 0;

/* 指纹运行状态数据 */
static Finger_Status_Data_stu_t finger_status_data;

/* 指纹组件状态 */
static FingerStatus_enum_t finger_status = FPSTATUS_INIT;

/* 控制休眠错误次数 */
static uint16_t dormanc_error_num = 0;

/* 超时时间内检测手指是否存在 */
static uint16_t finger_time_out = 200;       //时间为200ms

__NVRAM static uint8_t finger_wake_flag = 0;


/* 空闲时间 */
static uint16_t idleTime = 0;
/* 等待切换的指纹模式 */
static FingerMsgBuff_t fingerMsgBuff;
/**
  * @brief  复位NV里面Finger部分所有的数据
  *
  * @note   恢复出厂设置时调用
  */
static void Finger_NvReset(void)
{
    NvFinger_stu_t nvFinger; 
    memset(&nvFinger, 0, sizeof(nvFinger));             //清空NvFinger_stu_t结构体，指纹传感器类型sensor_type被初始化为0:3022
    nvFinger.nvInitFlag = FINGER_NV_INIT_FLAG;
    //保存user param
	OSAL_NvWrite(0, &nvFinger, sizeof(nvFinger));
}
/**
  * @brief  指纹传感器NV初始化
  * @note   
  * @return 0：3022 1：1021
  */
static void Finger_NvInit(void)
{
    NvFinger_stu_t nvFinger;
    uint8_t initFlag = 0;

    memset(&nvFinger, 0, sizeof(nvFinger));
    //读出数据
    OSAL_NvRead(0, &nvFinger, sizeof(NvFinger_stu_t));
    if(nvFinger.nvInitFlag != FINGER_NV_INIT_FLAG)
    {
        initFlag = 1;
    }
    else
    {
        if(nvFinger.sensor_type != 0 && nvFinger.sensor_type != 1)
        {
            initFlag = 1;
        }
    }
    if(initFlag)//需要执行初始化
    {
        FINGER_LOG("Finger Nv Reset\r\n");
        Finger_NvReset();
    }

    /* flash异常检测 */
    uint8_t err = 0;
    memset(&nvFinger, 0, sizeof(nvFinger));
    OSAL_NvRead(0, &nvFinger, sizeof(NvFinger_stu_t));
    if (nvFinger.nvInitFlag != FINGER_NV_INIT_FLAG)
    {
        err = 1;
    }
    OSAL_MessagePublishErrorCode(ERRCODE_TYPE_FLASH, err);
}

/**
  * @brief  获取保存在NV的指纹传感器类型
  * @note   
  * @return 0：3022 1：1021
  */
static uint8_t Finger_GetNvSensorType(void)
{
    uint8_t sensorType;
    //读出数据
    OSAL_NvRead(OSAL_OFFSET(NvFinger_stu_t, sensor_type), &sensorType, sizeof(uint8_t));
    return sensorType;
}

/**
  * @brief  设置保存在NV的指纹传感器类型
  * @note   
  * @param  0：3022 1：1021
  */
static ErrorStatus Finger_SetNvSensorType(uint8_t sensorType)
{
	uint8_t nvsensorType = Finger_GetNvSensorType();
	if(nvsensorType == sensorType)//指纹类型没改变,不执行保存操作,直接返回成功
	{
		return SUCCESS;
	}
	else
	{
		//保存数据
		return OSAL_NvWrite(OSAL_OFFSET(NvFinger_stu_t, sensor_type), &sensorType, sizeof(uint8_t));
	}
}


/**
  * @brief  指纹模块算法初始化
  * @note   匹配TSV工艺的FPC3022指纹模块的算法库lib21仅支持3022的sensor，不支持1021的sensor
  * @param  
  * @return
  */
static fpc_bep_result_t Finger_Sensor_Algorithm_Init(Finger_Status_Data_stu_t *status)
{
    fpc_bep_result_t result = FPC_BEP_RESULT_GENERAL_ERROR; //函数返回结果
    fpc_bep_bio_param_t param;
    fpc_bep_sensor_param_t sensor_param;
    fpc_bep_algorithm_t *algorithm;

    status->mode = WORK_MODE_VERIFY;
    status->image = NULL;
    status->template_read = NULL;
    status->enroll_num = 0;

    FINGER_LOG("Finger_Sensor_Algorithm_Init start\r\n");
    uint8_t sensorType = Finger_GetNvSensorType();
    if (sensorType == 0) //3022指纹模块
    {
        result = fpc_bep_bio_get_recommended_param(&fpc_bep_algorithm_pfe_1261, &param);
        FINGER_LOG("result = %d\r\n", result);
		FINGER_LOG("FPC_BEP_RESULT_OK = %d\r\n", FPC_BEP_RESULT_OK);
		fpc_assert(result == FPC_BEP_RESULT_OK);

        result = fpc_bep_sensor_get_recommended_param(&fpc_bep_sensor_1261, &sensor_param);
        fpc_assert(result == FPC_BEP_RESULT_OK);

        //测试是否是3022的指纹头
        result = fpc_bep_sensor_init(&fpc_bep_sensor_1261, NULL, &sensor_param);
        FINGER_LOG("fpc_bep_sensor_init result = %d \n", result);
        if (result == FPC_BEP_RESULT_OK)
        {
            status->sensor_init_flag = true;
            param.enroll.min_image_quality = 50;                            //录入图像质量阀值（官方建议值：50）
            param.identify.template_update = FPC_BEP_CONFIG_ENABLE;         //模板更新
            param.enroll.nbr_of_images = 8;                                 //录入次数
            param.enroll.min_sensor_coverage = 70;                          //录入覆盖面积阀值（官方建议值：70）
            result = fpc_bep_bio_init(&param, &fpc_bep_algorithm_pfe_1261);
            fpc_assert(result == FPC_BEP_RESULT_OK);
            status->sensor_type = FPC_BEP_SENSOR_TYPE_FPC1261;              //3022指纹头
            algorithm = (fpc_bep_algorithm_t *)&fpc_bep_algorithm_pfe_1261;
            status->enrollment_status.samples_remaining = param.enroll.nbr_of_images;
            FINGER_LOG("sensor type:FPC3022\n");
        }
        else 
        {
            fpc_sensor_spi_reset(true);
            Device_DelayMs(3);
            fpc_sensor_spi_reset(false);
            result = fpc_bep_bio_get_recommended_param(&fpc_bep_algorithm_pfe_1261, &param);
            FINGER_LOG("result = %d\r\n", result);
            FINGER_LOG("FPC_BEP_RESULT_OK = %d\r\n", FPC_BEP_RESULT_OK);
            fpc_assert(result == FPC_BEP_RESULT_OK);

            result = fpc_bep_sensor_get_recommended_param(&fpc_bep_sensor_1261, &sensor_param);
            fpc_assert(result == FPC_BEP_RESULT_OK);

            //测试是否是3022的指纹头
            result = fpc_bep_sensor_init(&fpc_bep_sensor_1261, NULL, &sensor_param);
            FINGER_LOG("fpc_bep_sensor_init result = %d \n", result);
            if (result == FPC_BEP_RESULT_OK)
            {
                status->sensor_init_flag = true;
                param.enroll.min_image_quality = 50;                            //录入图像质量阀值（官方建议值：50）
                param.identify.template_update = FPC_BEP_CONFIG_ENABLE;         //模板更新
                param.enroll.nbr_of_images = 8;                                 //录入次数
                param.enroll.min_sensor_coverage = 70;                          //录入覆盖面积阀值（官方建议值：70）
                result = fpc_bep_bio_init(&param, &fpc_bep_algorithm_pfe_1261);
                fpc_assert(result == FPC_BEP_RESULT_OK);
                status->sensor_type = FPC_BEP_SENSOR_TYPE_FPC1261;              //3022指纹头
                algorithm = (fpc_bep_algorithm_t *)&fpc_bep_algorithm_pfe_1261;
                status->enrollment_status.samples_remaining = param.enroll.nbr_of_images;
                FINGER_LOG("sensor type:FPC3022\n");
            }
            else
            {
                return result;
            }
        }
    }
    else
    {
        return result;
    }

    //打印算法的参数
//    FINGER_LOG("nbr_of_finger_present_zones = %d \n",sensor_param.nbr_of_finger_present_zones);
//    FINGER_LOG("driver_mechanism = %d \n",sensor_param.driver_mechanism);
//    FINGER_LOG("reset = %d \r\n",sensor_param.reset);
//    FINGER_LOG("param.enroll.min_sensor_coverage = %d \n",param.enroll.min_sensor_coverage);
//    FINGER_LOG("param.enroll.min_image_quality = %d \n",param.enroll.min_image_quality);
//    FINGER_LOG("param.enroll.nbr_of_images = %d \n",param.enroll.nbr_of_images);
//    FINGER_LOG("param.identify.security_level = %d \n",param.identify.security_level);
//    FINGER_LOG("param.enroll.scheme = %d \n",param.enroll.scheme);
//    FINGER_LOG("param.identify.template_update = %d \n",param.identify.template_update);
//    FINGER_LOG("param.general.latency_scheme = %d \n",param.general.latency_scheme);

    status->nbr_of_images = param.enroll.nbr_of_images;

    result = fpc_bep_algorithm_get_max_template_size(algorithm, &(status->template_max_size));
    FINGER_LOG("result= %d\r\n", result);
	FINGER_LOG("template_max_size= %d\r\n", status->template_max_size);
	fpc_assert(result == FPC_BEP_RESULT_OK);

    if (sensorType == 0)
	{
		FINGER_LOG("SENSOR_SLEEP_PERIOD_3022\r\n");
        status->sensor_sleep_period = SENSOR_SLEEP_PERIOD_3022;
	}

    result = fpc_bep_sensor_sleep(20);
    FINGER_LOG("fpc_bep_sensor_sleep result :%d", result);
    fpc_assert(result == FPC_BEP_RESULT_OK);

    if (!Finger_SetNvSensorType(sensorType))
        FINGER_LOG("sensor type save error\r\n");
    return result;
}

/**
  * @brief  验证模板
  * @note   
  *         
  * @param  index ：输出模板的索引号
  * @param  start ：开始搜索的位置
  * @param  end ：结束搜索的位置
  * @return -1：失败  ，成功：返回搜索到的指纹号码
  */
static int Finger_Verify_Temp(Finger_Status_Data_stu_t *data, uint16_t start, uint16_t end)
{
    fpc_bep_result_t result;
    fpc_bep_identify_result_t identify_result = {false, 0};
    int res = -1;
    for (uint16_t i = start; i < end; i++)
    {
        if (!fpc_read_temp(&data->template_read, data->verif_list.list[i].index_id)) //读取模板
        {
            result = fpc_bep_template_delete(&(data->template_read));
            if (result != FPC_BEP_RESULT_OK)
            {
                FINGER_LOG("fpc_bep_template_delete is error,error code = %d\r\n", result);
                break;
            }
            continue;
        }
        result = fpc_bep_identify((const fpc_bep_template_t **)&(data->template_read), 1, &identify_result); //对比模板
        if (result != FPC_BEP_RESULT_OK)
        {
            FINGER_LOG("fpc_bep_identify is error , error code = %d\r\n", result);
            result = fpc_bep_template_delete(&(data->template_read));
            if (result != FPC_BEP_RESULT_OK)
            {
                FINGER_LOG("fpc_bep_template_delete is error,error code = %d\r\n", result);
            }
            break;
        }
        else
        {
            if (identify_result.match)
            {
                res = data->verif_list.list[i].fpc_num; //指纹编号
                break;
            }
        }

        result = fpc_bep_template_delete(&(data->template_read));
        if (result != FPC_BEP_RESULT_OK)
        {
            FINGER_LOG("fpc_bep_template_delete is error,error code = %d\r\n", result);
            break;
        }
    }
    return res;
}

/**
  * @brief  查找指纹
  * @note   
  * @param  
  */
static int Finger_Search(Finger_Status_Data_stu_t *data)
{
    int fpc_num = -1;
    uint8_t list1 = 0;
    uint16_t len = fpc_read_verify_num(&(data->verif_list));
    static bool flag = false;

    FINGER_LOG("temp size :%d\r\n", len);


    if (data->sensor_type == FPC_BEP_SENSOR_TYPE_FPC1261)
    {
        if (len <= 55)
        {
            fpc_num = Finger_Verify_Temp(data, 0, len);
            FINGER_LOG("start=%d,end=%d\r\n", 0, len);
        }
        else
        {
            list1 = (len - 10) / 2;
            fpc_num = Finger_Verify_Temp(data, 0, 10); //搜索常用指纹
            FINGER_LOG("list0,start=%d,end=%d\r\n", 0, 10);
            if (fpc_num == -1)
            {
                if (!flag)
                {
                    fpc_num = Finger_Verify_Temp(data, 10, list1 + 10);
                    FINGER_LOG("list1,start=%d,end=%d\r\n", 10, list1 + 10);
                }
                else
                {
                    fpc_num = Finger_Verify_Temp(data, list1 + 10, len);
                    FINGER_LOG("list2,start=%d,end=%d\r\n", list1 + 10, len);
                }
                flag = !flag;
            }
        }
    }
    else
    {
        FINGER_LOG("unkown sensor type = %d\r\n", data->sensor_type);
    }
    
    FINGER_LOG("search fpc_num %d\r\n", fpc_num);
    return fpc_num;
}


/**
  * @brief  更新模板
  * @note   
  * @param  
  */
static int Finger_Update_temp(int fpc_num,Finger_Status_Data_stu_t *data)
{
    bool update_template;
    fpc_bep_result_t result;
    result = fpc_bep_identify_release(&update_template);
    if (result != FPC_BEP_RESULT_OK)
    {
        FINGER_LOG("fpc_bep_identify_release is error,error code = %d\r\n", result);
    }
    FINGER_LOG("identify_release finish\r\n");


    if (update_template && fpc_num != -1)
    {
        if (!fpc_save_temp( (const fpc_bep_template_t **)&(data->template_read), fpc_num, false) )
        {
            FINGER_LOG("fpc_save_temp error\r\n");
        }
    }
    else
    {
        result = fpc_bep_template_delete(&(data->template_read));
        if (result != FPC_BEP_RESULT_OK)
        {
            FINGER_LOG("fpc_bep_template_delete is error,error code = %d\r\n", result);
        }
    }
    return 0;
}

/**
  * @brief  ：在超时时间内一直检测手指是否存在
  * @note   
  * param  timeout:超时时间      
  * @return ：fpc_bep_result_t状态 若手指还在,返回FPC_BEP_RESULT_OK
  */
static fpc_bep_result_t Finger_Detect_Finger(uint32_t timeout)
{
    uint32_t start_time;
    fpc_bep_result_t result;
    fpc_bep_finger_status_t finger_present;

    result = fpc_bep_sensor_sleep(20);
    if (result != FPC_BEP_RESULT_OK)
    {
        return result;
    }

    start_time = fpc_timebase_get_tick();
    while (1)
    {
        //!TODO
        //OSAL_DelayUs(1000);
        if (timeout)
        {
            uint32_t time = fpc_timebase_get_tick() - start_time;
            if (time > timeout)
            {
                result = fpc_bep_sensor_deep_sleep();
                if (result == FPC_BEP_RESULT_OK)
                {
                    result = FPC_BEP_RESULT_TIMEOUT;
                }
                return result;
            }
        }

        if (!fpc_bep_finger_detect())
        {
            continue;
        }

        result = fpc_bep_check_finger_present(&finger_present);
        if (result != FPC_BEP_RESULT_OK || finger_present == FPC_BEP_FINGER_STATUS_PRESENT)
        {
            break;
        }

        result = fpc_bep_sensor_sleep(20);
        if (result != FPC_BEP_RESULT_OK)
        {
            break;
        }
    }
    return result;
}

/**
  * @brief:指纹添加失败
  * @note
  * @param
  */
static void Finger_Add_Fail(Finger_Status_Data_stu_t *data)
{
    FingerMsg_t fingerMsg;
    
    memset(&fingerMsg, 0, sizeof(fingerMsg));
	data->enroll_num = 0;
	finsh_flag = RESET;
	data->enrollment_status.samples_remaining = data->nbr_of_images;
	//注册失败
	FINGER_LOG("fpc_bep_enroll_finish res :%d\r\n", fpc_bep_enroll_finish(NULL));
	FINGER_LOG("FP_ACTION_ADD_ERR\r\n");
	fingerMsg.action = FINGER_ACTION_ADD_ERR;
	fingerMsg.fingerNumber = temp_save_num;
	OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));    
}

/**
  * @brief
  * @note
  * @param
  * @return
  */
static void Finger_Processor(void)
{
    FingerMsg_t fingerMsg;
    fpc_bep_result_t res;
    fpc_bep_template_t *template_enroll = NULL;
    static uint32_t start_time;
    static fpc_bep_result_t finger_away_result;     /* 手指离开结果 */
    FINGER_LOG("Finger_ProcessorTimer finger_status = %d\r\n", finger_status);

    switch (finger_status)
    {
        case FPSTATUS_INIT:       /* 初始化 */
            memset(&fingerMsg, 0, sizeof(fingerMsg));
            if (finger_status_data.mode == WORK_MODE_ADD)
            {
                if (!finsh_flag)
                {
                    res = fpc_bep_enroll_start();                       //开始注册会话
                    if (res != FPC_BEP_RESULT_OK)
                    {
                        FINGER_LOG("fpc_bep_enroll_start error\r\n");
                        fpc_bep_enroll_finish(NULL);                    //取消注册会话
                        res = fpc_bep_enroll_start();
                    }

                    if (res == FPC_BEP_RESULT_OK)
                    {
                        finsh_flag = SET;
                        FINGER_LOG("fpc_bep_enroll_start\r\n");
                    }
                    else
                    {
                        FINGER_LOG("fpc_bep_enroll_error\r\n");
                        dormanc_error_num = 0;

                        finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;  //切换到开始等待手指挪开
                        return;
                    }
                }
            }
            if (finger_status_data.mode == WORK_MODE_DISABLE)
            {
                dormanc_error_num = 0;
                finger_status = FPSTATUS_DORMANCY;                  //切换到休眠
                return;
            }

            if (finger_status_data.image == NULL)
            {
                FINGER_LOG("finger_status_data.image new\r\n");
                finger_status_data.image = fpc_bep_image_new();
            }
            fpc_assert(finger_status_data.image != NULL);

            FINGER_LOG(" Detect Finger\r\n");
            if (Finger_Detect_Finger(200) != FPC_BEP_RESULT_OK)
            {
                FINGER_LOG("get image timeout\r\n");
                dormanc_error_num = 0;
                
                finger_status = FPSTATUS_DORMANCY;                  //采图失败,直接休眠
                return;
            }
            FINGER_LOG(" Captures an image  \r\n");


            res = fpc_bep_capture(finger_status_data.image);        //获取指纹图像
            if (res != FPC_BEP_RESULT_OK)
            {
                FINGER_LOG("FINGER_ACTION_VERIFY_ERR: %d\r\n", res);
                dormanc_error_num = 0;
                finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;    //切换到开始等待手指挪开
                break;
            }
            else
            {
                FINGER_LOG("get image ok\r\n");
                fingerMsg.action = FINGER_ACTION_GET_IMAGE_OK;
                fingerMsg.fingerNumber = 0xff;
                OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));  //上报应用层指纹图像获取成功
                FINGER_LOG("finger_status_data.mode = %d\r\n", finger_status_data.mode);
                
                finger_status = FPSTATUS_GET_IMAGE_OK_HANDLE;
                idleTime = 1;
            }

        
        case FPSTATUS_GET_IMAGE_OK_HANDLE:          /* 采图成功处理 */
            if (finger_status_data.mode == WORK_MODE_VERIFY)
            {
                FINGER_LOG("mode == WORK_MODE_VERIFY\r\n");
                fpc_bep_enroll_finish(NULL);                        //取消注册会话
                finsh_flag = RESET;
                res = fpc_bep_image_extract(&(finger_status_data.image), NULL); //提取指纹图像特征
                if (res != FPC_BEP_RESULT_OK)
                {
                    bool update_template;
                    FINGER_LOG("fpc_bep_image_extract error : %d\r\n", res);
                    res = fpc_bep_identify_release(&update_template);
                    FINGER_LOG("fpc_bep_identify_release error : %d\r\n", res);
                    
                    dormanc_error_num = 0;
                    finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;  //切换到开始等待手指挪开
                    return;
                }
                else
                {
                    FINGER_LOG(" image extract success\r\n");
                    int num = Finger_Search(&finger_status_data);
                    if (num == -1)
                    {
                        FINGER_LOG("FINGER_ACTION_VERIFY_ERR\r\n");
                        fingerMsg.action = FINGER_ACTION_VERIFY_ERR;
                        fingerMsg.fingerNumber = 0xff;
                        OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
                    }
                    else
                    {
                        //搜索到指纹
                        FINGER_LOG("FINGER_ACTION_VERIFY_OK\r\n");
                        fingerMsg.action = FINGER_ACTION_VERIFY_OK;
                        fingerMsg.fingerNumber = (uint8_t)num;
                        OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
                        idleTime = 20;
                    }
                    //更新模板
                    Finger_Update_temp(num,&finger_status_data);
                }
            }
            else if (finger_status_data.mode == WORK_MODE_ADD)
            {
                FINGER_LOG("mode == WORK_MODE_ADD\r\n");
                if (temp_save_num == 0xFF)
                {
                    FINGER_LOG("temp_save_num == 0xFF\r\n");
                    dormanc_error_num = 0;
                    Finger_Add_Fail(&finger_status_data);
                    finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;  //切换到开始等待手指挪开
                    return;
                }

                if (finger_status_data.enrollment_status.samples_remaining > 0)     //samples_remaining:完成录入剩余次数
                {
                    //fpc3022新算法库bep_lib21，fpc_bep_enroll()函数形参image由指针的指针类型更改为指针类型
                    res = fpc_bep_enroll((finger_status_data.image), &(finger_status_data.enrollment_status));
                    FINGER_LOG("res = %d, samples_remaining = %d\r\n", res, finger_status_data.enrollment_status.samples_remaining);
                    if (res == FPC_BEP_RESULT_TOO_MANY_BAD_IMAGES) //错误的图像太多
                    {
                        FINGER_LOG("finger get image error too much\r\n");
                        dormanc_error_num = 0;
                        Finger_Add_Fail(&finger_status_data);
                        finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;  //切换到开始等待手指挪开
                        return;
                    }
                }

                if (res != FPC_BEP_RESULT_OK)
                {
                    FINGER_LOG("fpc_bep_enroll error : %d\r\n", res);
                }
                else
                {
                    //判断注册状态
                    finger_status_data.enroll_num += 1;
                    FINGER_LOG("samples_remaining : %d,enroll_num :%d\r\n", 
                                finger_status_data.enrollment_status.samples_remaining, 
                                finger_status_data.enroll_num);
                    if (finger_status_data.enrollment_status.feedback == FPC_BEP_ENROLLMENT_DONE && 
                        finger_status_data.enrollment_status.samples_remaining == 0 && 
                        finger_status_data.enroll_num >= 8 && 
                        finger_status_data.enroll_num < MAX_REMAININ)
                    {
                        FINGER_LOG("fpc_bep_enroll_finish:%d\r\n", (uint32_t)template_enroll);
                        res = fpc_bep_enroll_finish(&template_enroll); //注册完成
                        if (res != FPC_BEP_RESULT_OK)
                        {
                            //注册失败
                            FINGER_LOG("fpc_bep_enroll_finish error :%d\r\n", res);
                            fpc_bep_template_delete(&template_enroll);
                            FINGER_LOG("FP_ACTION_ADD_ERR\r\n");
                            fingerMsg.action = FINGER_ACTION_ADD_ERR;
                            fingerMsg.fingerNumber = temp_save_num;
                            OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
                        }
                        else
                        {
                            FINGER_LOG("fpc_save_temp\r\n");
                            if (fpc_save_temp((const fpc_bep_template_t **)&template_enroll, temp_save_num, true)) //保存模板
                            {
                                FINGER_LOG("FP_ACTION_ADD_OK\r\n");
                                fingerMsg.action = FINGER_ACTION_ADD_OK;
                                fingerMsg.fingerNumber = temp_save_num;
                                OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
                            }
                            else
                            {
                                //保存失败
                                FINGER_LOG("finger save is fail\r\n");
                                fpc_bep_template_delete(&template_enroll);
                                FINGER_LOG("FP_ACTION_ADD_ERR\r\n");
                                fingerMsg.action = FINGER_ACTION_ADD_ERR;
                                fingerMsg.fingerNumber = temp_save_num;
                                OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
                            }
                        }
                        finsh_flag = RESET;
                        finger_status_data.enroll_num = 0;
                        finger_status_data.mode = WORK_MODE_DISABLE;
                        finger_status_data.enrollment_status.samples_remaining = finger_status_data.nbr_of_images;
                    }
                    else
                    {
                        FINGER_LOG("FINGER_ACTION_ENTER_AGAIN\r\n");
                        fingerMsg.action = FINGER_ACTION_ENTER_AGAIN;
                        fingerMsg.fingerNumber = temp_save_num;
                        OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
                    }

                    if (finger_status_data.enroll_num >= MAX_REMAININ)
                    {
                        FINGER_LOG("finger enroll is surpass %d\r\n", MAX_REMAININ);
                        
                        dormanc_error_num = 0;
                        Finger_Add_Fail(&finger_status_data);
                        finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;  //切换到开始等待手指挪开
                        return;
                    }
                }
            }
            dormanc_error_num = 0;
            finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;  //切换到开始等待手指挪开
            break;

        case FPSTATUS_WAIT_FINGER_AWAY_START:       /* 开始等待手指挪开 */
            if (finger_status_data.image == NULL)
            {
                finger_status_data.image = fpc_bep_image_new();
            }
            fpc_assert(finger_status_data.image != NULL); 

            start_time = fpc_timebase_get_tick();               //记录起始时间
            finger_status = FPSTATUS_DETECT_FINGER;             //切换状态为手指检测

            finger_away_result = fpc_bep_sensor_sleep(20);
            if (finger_away_result != FPC_BEP_RESULT_OK)
            {
                finger_status = FPSTATUS_WAIT_FINGER_AWAY_ING;//有检测结果了,切换状态
                return;
            }
            break;

        case FPSTATUS_DETECT_FINGER:          /* 超时时间内检测手指是否存在 */
        {
            fpc_bep_finger_status_t finger_present;

            if (finger_time_out)//超时设置不为0
            {
                uint32_t time = fpc_timebase_get_tick() - start_time;
                if (time > finger_time_out)
                {
                    finger_away_result = fpc_bep_sensor_deep_sleep();
                    if (finger_away_result == FPC_BEP_RESULT_OK)
                    {
                        finger_away_result = FPC_BEP_RESULT_TIMEOUT;
                    }
                    finger_status = FPSTATUS_WAIT_FINGER_AWAY_ING;//有检测结果了,切换状态,超时切换
                    return;
                }
            }
            if (!fpc_bep_finger_detect())
            {
                finger_status = FPSTATUS_DETECT_FINGER;//手指没有离开,继续检测
                return;
            }

            finger_away_result = fpc_bep_check_finger_present(&finger_present);
            if (finger_away_result != FPC_BEP_RESULT_OK || finger_present == FPC_BEP_FINGER_STATUS_PRESENT)
            {
                finger_status = FPSTATUS_WAIT_FINGER_AWAY_ING;//有检测结果了,切换状态,手指离开切换
                return;
            }

            finger_away_result = fpc_bep_sensor_sleep(20);
            if (finger_away_result != FPC_BEP_RESULT_OK)
            {
                finger_status = FPSTATUS_WAIT_FINGER_AWAY_ING;//有检测结果了,切换状态
                return;
            }
        }
            break;

        case FPSTATUS_WAIT_FINGER_AWAY_ING:       /* 正在等待手指挪开 */
            if(finger_away_result == FPC_BEP_RESULT_OK || finger_away_result == FPC_BEP_RESULT_TIMEOUT)     //如果手指没有离开
            {
                res = fpc_bep_capture(finger_status_data.image);
                if(res != FPC_BEP_RESULT_OK)    //如果捕获不了图像,说明手指离开了
                {
                    finger_status = FPSTATUS_DORMANCY;  //标记下次进入休眠状态
                    fpc_bep_image_delete(&(finger_status_data.image));
                    //FINGER_LOG("fpc_bep_image_delete\n");  
                }
            }
            else
            {
                finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;
                return;
            }
            break;

        case FPSTATUS_DORMANCY:            /* 休眠操作 */
            fpc_bep_finger_detect();
            res = fpc_bep_sensor_sleep(finger_status_data.sensor_sleep_period);
            // FINGER_LOG("fpc_bep_sensor_sleep result :%d,sensor_sleep_period:%d", res, data->sensor_sleep_period);
            if (res != FPC_BEP_RESULT_OK)
            {
                FINGER_LOG("sensor sleep error\n");
                if (++dormanc_error_num < 10) //休眠10次错误
                {
                    if (finger_status_data.mode == WORK_MODE_DISABLE)
                    {
                        return;
                    }
                    else
                    {
                        finger_status = FPSTATUS_WAIT_FINGER_AWAY_START;
                        return ;
                    }
                }
            }
            else
            {
                if (fpc_sensor_spi_check_irq()) 
                {
                    return;
                }
            }
            finger_status = FPSTATUS_END;
            break;
            
        case FPSTATUS_END:              /* 结束操作 */
            if (fpc_sensor_spi_check_irq()) 
            {
                finger_status = FPSTATUS_DORMANCY;  //标记下次进入休眠状态
                FINGER_LOG("finger_status = FPSTATUS_DORMANCY\r\n");
                return;
            }
            OSAL_EventDelete(COMP_FINGER, EVENT_FINGER_DETECT);//删除事件
            finger_status = FPSTATUS_INIT;
            start_flag = RESET;

            OSAL_SetTaskStatus(TASK_STA_NORMAL); //指纹流程结束：允许系统休眠
            break;

        default:
            break;
    }
}

/**
  * @brief  指纹中断处理
  * @note   
  * @return 
  */
static void Finger_Sensor_Int_Irq_Handler(char *name, uint8_t status, uint8_t times)
{
    if (status == INPUT_PORT_STA_PRESS && times != 0xFF)
    {
        /* 创建ISR事件 */
        OSAL_EventCreateFromISR(COMP_FINGER);
    }
}

/**
  * @brief  指纹组件初始化
  * @note   
  * @return 
  */
static void Finger_Init(FlagStatus sleep)
{
    if (finger_init_flag == RESET)
    {
        Device_DelayMs(5);
        memset(&finger_status_data, 0, sizeof(finger_status_data));
        Finger_NvInit();
        if (Finger_Sensor_Algorithm_Init(&finger_status_data) != FPC_BEP_RESULT_OK)
        {
            OSAL_MessagePublishErrorCode(ERRCODE_TYPE_FINGER, 1);
            FINGER_LOG("Finger_Sensor_Algorithm_Init error! \r\n");
            return;
        }
        OSAL_MessagePublishErrorCode(ERRCODE_TYPE_FINGER, 0);
        if (!fpc_store_init(finger_status_data.template_max_size, &(finger_status_data.verif_list)))
        {
            FINGER_LOG("fpc_store_init error! \r\n");
            return;
        }

		InputPort_stu_t button_list[] = 
		{
			{"FINGER_INT", IRQ_VHW_FINGER, INPUT_PORT_LOGIC_HIGH, INPUT_PORT_FUNC_SINGLE}, //中断脚
        };
        /* 注册端口 */
        InputPort_Registered(button_list, OSAL_LENGTH(button_list), Finger_Sensor_Int_Irq_Handler);
        InputPort_EnableProt("FINGER_INT");	

        if (sleep == SET)
        {
            uint8_t error_num = 0;
            FINGER_LOG("fpc_sensor sleep\r\n");
            fpc_bep_result_t res = fpc_bep_sensor_sleep(finger_status_data.sensor_sleep_period);
            while(res != FPC_BEP_RESULT_OK && error_num++ <= 10)
            {
                res = fpc_bep_sensor_sleep(finger_status_data.sensor_sleep_period);
            }
            if(error_num >= 10)
            {
                FINGER_LOG("fpc sleep error\r\n");
            }
        }	
        finger_init_flag = SET;
    }
}

/**
  * @brief  指纹组件中断事件处理
  * @note        
  */
static void Finger_Isr_Event_Handle(void)
{
    if (!start_flag)
    {
        start_flag = SET;

        FINGER_LOG("finger_status_data.mode: %d\r\n", finger_status_data.mode);
        OSAL_EventRepeatCreate(COMP_FINGER, EVENT_FINGER_DETECT, FINGER_PROCESSOR_TIME, EVT_PRIORITY_MEDIUM);
        OSAL_SetTaskStatus(TASK_STA_ACTIVE); //指纹流程开始：禁止系统休眠
    }
}

static void Finger_ProcessMbox(uint8_t *msg)
{
    if(finger_init_flag == RESET)
    {
        memset(&fingerMsgBuff,0,sizeof(fingerMsgBuff));
        memcpy(&fingerMsgBuff,msg,sizeof(fingerMsgBuff));
        OSAL_EventSingleCreate(COMP_FINGER, EVENT_MSG_BUFF_PROCESS, 1010, EVT_PRIORITY_MEDIUM);      //指纹还未初始化 1010ms后再改变工作模式
        FINGER_LOG("after 1010ms process App msg_type:%d,data[0]:%d,data[1]:%d\r\n",fingerMsgBuff.msg_type,fingerMsgBuff.msg_data[0],fingerMsgBuff.msg_data[1]);
        return;
    }

    switch (msg[0])
    {
		case FINGER_SETWORKMODE:		//切换指纹任务工作模式
		{
			uint8_t mode;
			mode = msg[1];
			temp_save_num = msg[2];         //
            if (mode != finger_status_data.mode)
            {
                finger_status_data.mode = (WorkMode_enum_t)mode;
                if (finger_status_data.mode == FINGER_WORK_MODE_ADD)
                {
                    FINGER_LOG("switch add mode\r\n");
                }
                else if (finger_status_data.mode == FINGER_WORK_MODE_VERIFY)
                {
                    FINGER_LOG("switch verify mode\r\n");
                }
                else if (finger_status_data.mode == FINGER_WORK_MODE_DISABLE)
                {
                    FINGER_LOG("switch disable mode\r\n");
                }
                finsh_flag = RESET;
                fpc_bep_enroll_finish(NULL); //取消注册会话
                finger_status_data.enroll_num = 0;  //注册次数清零
            }
            FINGER_LOG("finger work mode :%d, fpc_num :%d\r\n", mode, temp_save_num);
		}
			break;
		case FINGER_DELETEIMAGE:		//删除指纹图像
		{
			uint8_t startNum, endNum;
			startNum = msg[1];
			endNum = msg[2];
			FINGER_LOG("Users_DeleteFingerImage: startNum = 0x%02x, endNum = 0x%02x\r\n", startNum, endNum);
			if (startNum == 0XFF && endNum == 0XFF)
			{
				fpc_store_empty();	
			}
			else
			{
				fpc_del_num(startNum, endNum);
			}
		}
			break;
		default:
			break;
    }
}
/**
 * @brief 指纹模式切换
 * 
 */
static void FingerMsgBuffProcess(void)
{
    if(fingerMsgBuff.msg_type == FINGER_SETWORKMODE)
    {
        temp_save_num =  fingerMsgBuff.msg_data[1];
        if (fingerMsgBuff.msg_data[0] != finger_status_data.mode)
        {
            finger_status_data.mode = fingerMsgBuff.msg_data[0];
            if (finger_status_data.mode == FINGER_WORK_MODE_ADD)
            {
                FINGER_LOG("switch add mode\r\n");
            }
            else if (finger_status_data.mode == FINGER_WORK_MODE_VERIFY)
            {
                FINGER_LOG("switch verify mode\r\n");
            }
            else if (finger_status_data.mode == FINGER_WORK_MODE_DISABLE)
            {
                FINGER_LOG("switch disable mode\r\n");
            }
            finsh_flag = RESET;
            fpc_bep_enroll_finish(NULL); //取消注册会话
            finger_status_data.enroll_num = 0;  //注册次数清零
        }
        FINGER_LOG("finger work mode :%d, fpc_num :%d\r\n", finger_status_data.mode, temp_save_num);
    }
    else if(fingerMsgBuff.msg_type == FINGER_DELETEIMAGE)
    {
        uint8_t startNum =0, endNum=0;
        startNum = fingerMsgBuff.msg_data[0];
        endNum =fingerMsgBuff.msg_data[1];
        FINGER_LOG("Users_DeleteFingerImage: startNum = 0x%02x, endNum = 0x%02x\r\n", startNum, endNum);
        if (startNum == 0XFF && endNum == 0XFF)
        {
            fpc_store_empty();	
        }
        else
        {
            fpc_del_num(startNum, endNum);
        }
    }
}



/**
  * @brief  FINGER任务函数
  *
  * @note   1.任务函数内不能写阻塞代码
  *         2.任务函数每次运行只处理一个事件
  *         
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t Finger_Task(uint32_t event)
{
    /* 系统启动事件 */
    if (event & EVENT_SYS_START)
    {
        FINGER_LOG("Finger task start\r\n");
        Device_Enable(vSPI_1);
        if (finger_wake_flag == 1)                                                                  //指纹外部中断唤醒启动
        {
            finger_wake_flag = 0;
            Finger_Init(RESET);
        }
        else
        {
            OSAL_EventSingleCreate(COMP_FINGER, EVENT_INIT_FINGER, 1000, EVT_PRIORITY_MEDIUM);      //非指纹外部中断唤醒启动
        }
        return ( event ^ EVENT_SYS_START );
    }

    /* 不是指纹唤醒就延迟初始化指纹 */
    if (event & EVENT_INIT_FINGER)
    {
        Finger_Init(SET);
        return ( event ^ EVENT_INIT_FINGER );
    }

    /* 系统中断事件 */
    if (event & EVENT_SYS_ISR)
    {
        Finger_Isr_Event_Handle();
        return ( event ^ EVENT_SYS_ISR );
    }
    /*修改指纹模式*/
    if (event & EVENT_MSG_BUFF_PROCESS)
    {
        FingerMsgBuffProcess();
        return ( event ^ EVENT_MSG_BUFF_PROCESS );
    }
    if (event & EVENT_FINGER_DETECT)
	{
		if (idleTime > 0)/* 指纹验证成功后,1秒钟内不处理指纹任何事情,留给psensor处理时间 */
		{
			idleTime--;
		}
		else
		{
			Finger_Processor();
		}
        return ( event ^ EVENT_FINGER_DETECT );
    }
	
	if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[50] = {0};
        while (OSAL_MboxAccept(buffer))
        {
            Finger_ProcessMbox(buffer);
        }
        return ( event ^ EVENT_SYS_MBOX );
    }

    /* 系统休眠事件 */
    if (event & EVENT_SYS_SLEEP)
    {
        Device_Disable(vSPI_1);
        FINGER_LOG("Finger task sleep\r\n");
        return ( event ^ EVENT_SYS_SLEEP );
    }
    return 0;
}
COMPONENT_TASK_EXPORT(COMP_FINGER, Finger_Task, FINGER_NV_SIZE);

/**
  * @brief  指纹唤醒逻辑处理
  * @param  
  * @return 
  */
static int32_t Finger_WakeHandle(uint32_t dev)
{
    finger_wake_flag = 1;
    return 1; //TODO消抖
}
COMPONENT_WAKEUP_EXPORT(COMP_FINGER, Finger_WakeHandle, IRQ_VHW_FINGER);
